package com.cs307.redcross.client;

import java.io.Serializable;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;

public class AdminUserContent extends Content implements Serializable {
	private static final long serialVersionUID = -1189011235559691201L;
	private DatabaseHandlerServiceAsync databaseHandlerService = (DatabaseHandlerServiceAsync) GWT.create(DatabaseHandlerService.class);
	private final String relogString = "If this problem persists try relogging into the system.";
	
	Vector<Volunteer> volunteersVector = new Vector<Volunteer>();	
	Vector<Administrator> adminVector = new Vector<Administrator>();

	Volunteer selectedVolunteer;
	Volunteer cancelVolunteer;
	Administrator selectedAdmin;
	Administrator cancelAdmin;
	
	Person currentUser;
	
	// UI Widgets
	ListBox volunteersListbox;
	Button deleteVolunteerButton;
	Button editVolunteerButton;
	PopupPanel popup;
	AddPersonPopupPanel appp;
	LoadingPopupPanel lpp = new LoadingPopupPanel();
	Button addVolunteerButton;
	ListBox adminListBox;
	Label lblVolunteers;
	Button addAdminButton;
	Button deleteAdminButton;
	Button editAdminButton;
	ListBox cellCarrierCombobox;
	Label lblCellCarrier;
	TextBox cellPhoneNumberTextBox;
	Label lblCellPhone;
	TextBox emailTextBox;
	Label lblEmail;
	TextBox lastNameTextbox;
	Label lblLastName;
	TextBox firstNameTextbox;
	Label lblFirstName;
	Button saveVolunteerButton;
	Button cancelVolunteerButton;
	Button saveAdminButton;
	Button cancelAdminButton;
	Label passwordLabel;
	Label retypePasswordLabel;
	PasswordTextBox passwordTextBox;
	PasswordTextBox retypePasswordTextbox;
	ValidateIdentityDialogBox vidb;
	
	public AdminUserContent() {	
		currentUser = Server.currentUser;
		
		lpp.setAutoHideEnabled(false);
		lpp.setModal(true);
		
		//TODO: show loading
		updateListsOfPeople();
		
		
		AbsolutePanel absolutePanel = new AbsolutePanel();
		initWidget(absolutePanel);
		absolutePanel.setSize("592px", "647px");
		
		Label lblSelectEvent = new Label("Admins:");
		absolutePanel.add(lblSelectEvent, 10, 10);
		lblSelectEvent.setSize("63px", "18px");
		
		//the code to deletes a volunteer 
		deleteVolunteerButton = new Button("Delete");
		deleteVolunteerButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedVolunteer != null && volunteersListbox.getSelectedIndex() != -1) {
					vidb = new ValidateIdentityDialogBox();
					vidb.setModal(true);
					vidb.setGlassEnabled(true);
					vidb.setPopupPosition(200, 250);
					vidb.show();
					
					vidb.addCloseHandler(new CloseHandler<PopupPanel>(){
						public void onClose(CloseEvent<PopupPanel> event) {
							if (vidb.isValid) {
								databaseHandlerService.delete(selectedVolunteer, new AsyncCallback<Boolean>(){
									@Override
									public void onFailure(Throwable caught) {
										Window.alert("Error: failed to delete the administrator. " + relogString);
										return;								
									}

									@Override
									public void onSuccess(Boolean result) {
										volunteersListbox.removeItem(volunteersListbox.getSelectedIndex());
										volunteersVector.remove(selectedVolunteer);
										Window.alert("The volunteer " + selectedVolunteer.getFirstName() + " " + selectedVolunteer.getLastName() + " was sucessfully deleted.");
										selectedAdmin = null;
										clearForm();
									}
								});
							}
							else {
								return;
							}
						}
					});
				}
			}
		});
		absolutePanel.add(deleteVolunteerButton, 54, 604);
		deleteVolunteerButton.setSize("53px", "24px");
		
		//opens up the edit fild for a volunteer
		editVolunteerButton = new Button("Edit");
		editVolunteerButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (volunteersListbox.getSelectedIndex() != -1) {
					selectedVolunteer = volunteersVector.get(volunteersListbox.getSelectedIndex());
					enableForm(false);
					volunteersListbox.setEnabled(false);
				}
			}
		});
		absolutePanel.add(editVolunteerButton, 113, 604);
		editVolunteerButton.setSize("38px", "24px");
		
		//the listbox with all the volunteers
		volunteersListbox = new ListBox();
		volunteersListbox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (volunteersListbox.getSelectedIndex() != -1) {
					selectedVolunteer = volunteersVector.get(volunteersListbox.getSelectedIndex());
					populateForm(selectedVolunteer);
					adminListBox.setSelectedIndex(-1);
				}
			}
		});
		volunteersListbox.setVisibleItemCount(20);
		absolutePanel.add(volunteersListbox, 10, 207);
		volunteersListbox.setSize("259px", "391px");
		
		addVolunteerButton = new Button("Add");
		addVolunteerButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				enableForm(false);
				selectedVolunteer = new Volunteer();
				volunteersListbox.setSelectedIndex(-1);
				volunteersListbox.setEnabled(false);
				passwordLabel.setVisible(true);
				passwordTextBox.setVisible(true);
				retypePasswordLabel.setVisible(true);
				retypePasswordTextbox.setVisible(true);
				clearForm();
//				passwordTextBox.setText("");
//				retypePasswordTextbox.setText("");
//				cellPhoneNumberTextBox.setText("");
//				emailTextBox.setText("");
//				lastNameTextbox.setText("");
//				firstNameTextbox.setText("");
//				cellCarrierCombobox.setSelectedIndex(0);
			}
		});
		absolutePanel.add(addVolunteerButton, 10, 604);
		addVolunteerButton.setSize("38px", "24px");
		
		adminListBox = new ListBox();
		adminListBox.setVisibleItemCount(5);
		adminListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (adminListBox.getSelectedIndex() != -1) {
					selectedAdmin = adminVector.get(adminListBox.getSelectedIndex());
					populateForm(selectedAdmin);
					volunteersListbox.setSelectedIndex(-1);
				}
			}
		});
		absolutePanel.add(adminListBox, 10, 34);
		adminListBox.setSize("259px", "90px");
		
		lblVolunteers = new Label("Volunteers:");
		absolutePanel.add(lblVolunteers, 10, 183);
		lblVolunteers.setSize("79px", "18px");
		
		addAdminButton = new Button("Add");
		addAdminButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				enableForm(true);
				selectedAdmin = new Administrator();
				adminListBox.setSelectedIndex(-1);
				adminListBox.setEnabled(false);
				
				passwordLabel.setVisible(true);
				passwordTextBox.setVisible(true);
				retypePasswordLabel.setVisible(true);
				retypePasswordTextbox.setVisible(true);
				cellPhoneNumberTextBox.setText("");
				emailTextBox.setText("");
				lastNameTextbox.setText("");
				firstNameTextbox.setText("");
				cellCarrierCombobox.setSelectedIndex(0);
			}
		});
		absolutePanel.add(addAdminButton, 10, 130);
		addAdminButton.setSize("38px", "24px");
		
		deleteAdminButton = new Button("Delete");
		deleteAdminButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedAdmin.ID !=  currentUser.ID) {
					if (selectedAdmin != null && adminListBox.getSelectedIndex() != -1) {
	 					vidb = new ValidateIdentityDialogBox();
						vidb.setModal(true);
						vidb.setGlassEnabled(true);
						vidb.setPopupPosition(200, 250);
						vidb.show();
						
						vidb.addCloseHandler(new CloseHandler<PopupPanel>(){
							public void onClose(CloseEvent<PopupPanel> event) {
								if (vidb.isValid) {
									databaseHandlerService.delete(selectedAdmin, new AsyncCallback<Boolean>(){

										@Override
										public void onFailure(Throwable caught) {
											Window.alert("Error: failed to delete the administrator. " + relogString);
											return;								
										}

										@Override
										public void onSuccess(Boolean result) {
											adminListBox.removeItem(adminListBox.getSelectedIndex());
											adminVector.remove(selectedAdmin);
											Window.alert("The admin " + selectedAdmin.getFirstName() + " " + selectedAdmin.getLastName() + " was sucessfully deleted.");
											selectedAdmin = null;
											clearForm();
										}
									});
								}
								else {
									return;
								}
							}
						});
					}	
				}
				else
				{
					Window.alert("you cannot delete yourself");
				}
			}
		});
		absolutePanel.add(deleteAdminButton, 54, 130);
		deleteAdminButton.setSize("53px", "24px");
		
		editAdminButton = new Button("Edit");
		editAdminButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (adminListBox.getSelectedIndex() != -1) {
					selectedAdmin = adminVector.get(adminListBox.getSelectedIndex());
					enableForm(true);
					adminListBox.setEnabled(false);
				}
			}
		});
		absolutePanel.add(editAdminButton, 113, 130);
		editAdminButton.setSize("38px", "24px");
		
		cellCarrierCombobox = new ListBox();
		cellCarrierCombobox.addItem("AT&T");
		cellCarrierCombobox.addItem("Verizon");
		cellCarrierCombobox.addItem("T-Mobile");
		cellCarrierCombobox.addItem("Sprint PCS");
		cellCarrierCombobox.addItem("Virgin Mobile");
		cellCarrierCombobox.addItem("US Cellular");
		cellCarrierCombobox.addItem("Nextel");
		cellCarrierCombobox.addItem("Boost");
		cellCarrierCombobox.addItem("Alltel");
		absolutePanel.add(cellCarrierCombobox, 306, 280);
		cellCarrierCombobox.setSize("157px", "22px");
		
		lblCellCarrier = new Label("Cell Carrier:");
		absolutePanel.add(lblCellCarrier, 306, 256);
		lblCellCarrier.setSize("79px", "18px");
		
		cellPhoneNumberTextBox = new TextBox();
		cellPhoneNumberTextBox.setMaxLength(10);
		absolutePanel.add(cellPhoneNumberTextBox, 306, 225);
		cellPhoneNumberTextBox.setSize("150px", "14px");
		
		lblCellPhone = new Label("Cell Phone Number:");
		absolutePanel.add(lblCellPhone, 306, 201);
		lblCellPhone.setSize("119px", "18px");
		
		emailTextBox = new TextBox();
		absolutePanel.add(emailTextBox, 306, 153);
		emailTextBox.setSize("251px", "14px");
		
		lblEmail = new Label("Email:");
		absolutePanel.add(lblEmail, 306, 132);
		lblEmail.setSize("39px", "18px");
		
		lastNameTextbox = new TextBox();
		absolutePanel.add(lastNameTextbox, 306, 86);
		lastNameTextbox.setSize("251px", "14px");
		
		lblLastName = new Label("Last Name:");
		absolutePanel.add(lblLastName, 306, 62);
		lblLastName.setSize("79px", "18px");
		
		firstNameTextbox = new TextBox();
		firstNameTextbox.setFocus(true);
		absolutePanel.add(firstNameTextbox, 306, 34);
		firstNameTextbox.setSize("251px", "14px");
		
		lblFirstName = new Label("First Name:");
		absolutePanel.add(lblFirstName, 306, 10);
		lblFirstName.setSize("79px", "18px");
		
		saveVolunteerButton = new Button("Save");
		saveVolunteerButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (firstNameTextbox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("A first name is needed.");
					return;
				}
				if (lastNameTextbox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("A last name is needed.");
					return;
				}
				if (emailTextBox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("An email is needed.");
					return;
				}
				if (cellPhoneNumberTextBox.getText().replaceFirst(" ", "").equals("")) {
					//TODO: handle no phone number
				}
				if (!passwordTextBox.getText().equals(retypePasswordTextbox.getText())) {
					Window.alert("Passwords entered do not match each other.");
					return;
				}
				if (!ValidatePhoneNumber(cellPhoneNumberTextBox.getText())) {
					Window.alert("An valid cell phone number is needed.");
					return;
				}
				if (!ValidateEmailNumber(emailTextBox.getText()))
				{
					Window.alert("An valid email is need.");
					return;
				}
				
				//TODO: remove need for SMSemail
				
					
					selectedVolunteer.setFirstName(firstNameTextbox.getText()); 
					selectedVolunteer.setLastName(lastNameTextbox.getText());
					selectedVolunteer.setEmail(emailTextBox.getText());
					selectedVolunteer.setCarrier(cellCarrierCombobox.getItemText(cellCarrierCombobox.getSelectedIndex()));
					String pattern1 = "[^0-9]";
			    	String phoneNumber = cellPhoneNumberTextBox.getText().replaceAll(pattern1, "");
			    	selectedVolunteer.setCellPhoneNumber(phoneNumber);
					if( !passwordTextBox.getText().replaceFirst(" ", "").equals(""))
					{
						selectedVolunteer.setPassword(passwordTextBox.getText());
					}
				
				
				databaseHandlerService.write((Volunteer)selectedVolunteer, new AsyncCallback<Integer>() {
					@Override
					public void onSuccess(Integer result) {
						if (result > -1) {
							selectedVolunteer = null;
							updateListsOfPeople();
							
							Window.alert("The volunteer was succesfully updated.");
							disableForm();
						}
						else {
							Window.alert("Error: failed to save the new volunteer to the database. " + relogString);
							selectedVolunteer = null;
						}						
					}
					
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error: failed to save the new volunteer to the database. " + relogString);
						selectedVolunteer = null;
					}
				});
			}
		});
		absolutePanel.add(saveVolunteerButton, 10, 604);
		saveVolunteerButton.setSize("97px", "24px");
		
		cancelVolunteerButton = new Button("Save");
		cancelVolunteerButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				selectedVolunteer = null;
				clearForm();
				disableForm();
				volunteersListbox.setSelectedIndex(-1);
			}
		});
		cancelVolunteerButton.setText("Cancel");
		absolutePanel.add(cancelVolunteerButton, 113, 604);
		cancelVolunteerButton.setSize("97px", "24px");
		
		saveAdminButton = new Button("Save");
		saveAdminButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (firstNameTextbox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("A first name is needed.");
					return;
				}
				if (lastNameTextbox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("A last name is needed.");
					return;
				}
				if (emailTextBox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("An email is needed.");
					return;
				}
				if (cellPhoneNumberTextBox.getText().replaceFirst(" ", "").equals("")) {
					Window.alert("An cell phone number is needed.");
				}
				if (!passwordTextBox.getText().equals(retypePasswordTextbox.getText())) {
					Window.alert("The passwords entered do not match each other.");
					return;
				}
				if (!ValidatePhoneNumber(cellPhoneNumberTextBox.getText())) {
					Window.alert("An valid cell phone number is needed.");
					return;
				}
				if (!ValidateEmailNumber(emailTextBox.getText()))
				{
					Window.alert("An valid email is need.");
					return;
				}
				
				//TODO: remove need for SMSemail
				
				selectedAdmin.setFirstName(firstNameTextbox.getText()); 
				selectedAdmin.setLastName(lastNameTextbox.getText());
				selectedAdmin.setEmail(emailTextBox.getText());
				selectedAdmin.setCarrier(cellCarrierCombobox.getItemText(cellCarrierCombobox.getSelectedIndex()));
				String pattern1 = "[^0-9]";
		    	String phoneNumber = cellPhoneNumberTextBox.getText().replaceAll(pattern1, "");
		    	selectedAdmin.setCellPhoneNumber(phoneNumber);
				if( !passwordTextBox.getText().replaceFirst(" ", "").equals(""))
				{
					selectedAdmin.setPassword(passwordTextBox.getText());
				}

				databaseHandlerService.write((Administrator) selectedAdmin, new AsyncCallback<Integer>() {
					 
					@Override
					public void onSuccess(Integer result) {
						if (result > -1) {				
							Window.alert("The administrator was succesfully updated.");
							updateListsOfPeople();
							disableForm();
							
							if (currentUser.ID == selectedAdmin.ID)
							{
								databaseHandlerService.getAdmin(currentUser.ID, new AsyncCallback<Administrator>() {

									@Override
									public void onFailure(Throwable caught) {
										// TODO Auto-generated method stub
										
									}

									@Override
									public void onSuccess(Administrator result) {
										Server.currentUser = result;
										currentUser = result;
									}
									
								});
							}
						}
						else {
							Window.alert("Error: failed to save the new administrator to the database. " + relogString);
							selectedAdmin = null;
						}						
					}
					
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error: failed to save the new administrator to the database. " + relogString);
						selectedAdmin = null;
					}
				});
			}
		});
		absolutePanel.add(saveAdminButton, 10, 130);
		saveAdminButton.setSize("97px", "24px");
		
		cancelAdminButton = new Button("Save");
		cancelAdminButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				selectedAdmin = null;
				clearForm();
				disableForm();
				adminListBox.setSelectedIndex(-1);
			}
		});
		cancelAdminButton.setText("Cancel");
		absolutePanel.add(cancelAdminButton, 113, 130);
		cancelAdminButton.setSize("97px", "24px");
		
		passwordLabel = new Label("Password:");
		absolutePanel.add(passwordLabel, 306, 327);
		passwordLabel.setSize("64px", "18px");
		
		retypePasswordLabel = new Label("Retype Password:");
		absolutePanel.add(retypePasswordLabel, 306, 376);
		retypePasswordLabel.setSize("119px", "18px");
		
		passwordTextBox = new PasswordTextBox();
		absolutePanel.add(passwordTextBox, 306, 351);
		passwordTextBox.setSize("177px", "13px");
		
		retypePasswordTextbox = new PasswordTextBox();
		absolutePanel.add(retypePasswordTextbox, 306, 400);
		retypePasswordTextbox.setSize("177px", "13px");
		
		disableForm();
	}
		
	private void populateForm(Person person) {
		firstNameTextbox.setText(person.getFirstName());
		lastNameTextbox.setText(person.getLastName());
		emailTextBox.setText(person.getEmail());
		cellPhoneNumberTextBox.setText(person.getCellPhoneNumber());
		for (int i = 0; i < cellCarrierCombobox.getItemCount(); i++) {
			if (cellCarrierCombobox.getItemText(i).equals(person.getCarrier())) {
				cellCarrierCombobox.setSelectedIndex(i);
				break;
			}
		}
	}
	
	private void disableForm() {
		saveAdminButton.setVisible(false);
		cancelAdminButton.setVisible(false);

		saveVolunteerButton.setVisible(false);
		cancelVolunteerButton.setVisible(false);
		
		firstNameTextbox.setEnabled(false);
		lastNameTextbox.setEnabled(false);
		emailTextBox.setEnabled(false);
		cellPhoneNumberTextBox.setEnabled(false);
		cellCarrierCombobox.setEnabled(false);
		passwordLabel.setVisible(false);
		passwordTextBox.setVisible(false);
		retypePasswordLabel.setVisible(false);
		retypePasswordTextbox.setVisible(false);		
		
		volunteersListbox.setEnabled(true);
		addVolunteerButton.setEnabled(true);
		editVolunteerButton.setEnabled(true);
		deleteVolunteerButton.setEnabled(true);
		
		adminListBox.setEnabled(true);
		addAdminButton.setEnabled(true);
		editAdminButton.setEnabled(true);
		deleteAdminButton.setEnabled(true);
	}
	
	private void enableForm(boolean isAdmin) {
		firstNameTextbox.setEnabled(true);
		lastNameTextbox.setEnabled(true);
		emailTextBox.setEnabled(true);
		cellPhoneNumberTextBox.setEnabled(true);
		cellCarrierCombobox.setEnabled(true);
		
		if (isAdmin) {
			volunteersListbox.setEnabled(false);
			addVolunteerButton.setEnabled(false);
			editVolunteerButton.setEnabled(false);
			deleteVolunteerButton.setEnabled(false);
			
			saveAdminButton.setVisible(true);
			cancelAdminButton.setVisible(true);
			
			
		}
		else {
			adminListBox.setEnabled(false);
			addAdminButton.setEnabled(false);
			editAdminButton.setEnabled(false);
			deleteAdminButton.setEnabled(false);
						
			saveVolunteerButton.setVisible(true);
			cancelVolunteerButton.setVisible(true);
		}
	}
			
	private void clearForm() {
		firstNameTextbox.setText("");
		lastNameTextbox.setText("");
		emailTextBox.setText("");
		cellPhoneNumberTextBox.setText("");
		cellCarrierCombobox.setSelectedIndex(0);
		passwordTextBox.setText("");
		retypePasswordTextbox.setText("");
	}
	private void updateListsOfPeople()
	{
		// gets all the and puts them in the right list box 
		databaseHandlerService.getAllPeople(new AsyncCallback<Vector<Person>>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Error: failed to retrieve the list of Volunteers and Admins from the server. " + relogString);				
			}
			@Override
			public void onSuccess(Vector<Person> result) {
				volunteersVector.clear();
				volunteersListbox.clear();
				adminVector.clear();
				adminListBox.clear();
				if (result != null && !result.isEmpty()) {
					for (Person person : result) {
						if (person == null)
							continue;
						if (person.getUsername().equals("dev"))
							continue;
						if(person instanceof Volunteer) {
							volunteersVector.add((Volunteer)person);
							volunteersListbox.addItem(person.getFirstName() + " " + person.getLastName());
						}
						else {
							adminVector.add((Administrator)person);
							adminListBox.addItem(person.getFirstName() + " " + person.getLastName());
						}
					}
				}
			}
		});
	}
	
	public static boolean ValidatePhoneNumber(String phNumber)
    {
            boolean valResult = false;
            String numPattern = "^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$";
            valResult = phNumber.matches(numPattern);
            return valResult;
    }
	public static boolean ValidateEmailNumber(String email)
    {
            boolean valResult = false;
            String numPattern =  "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$";
            valResult = email.matches(numPattern);
            return valResult;
    }
	
}
